package com.hrp.analyzer.spider;

import androidx.core.util.Consumer;

import com.hrp.analyzer.common.page.AbstractPageable;
import com.hrp.analyzer.core.NovelMatcher;
import com.hrp.analyzer.core.helper.DebugHelper;
import com.hrp.analyzer.core.model.AnalyzerRule;
import com.hrp.analyzer.model.Novel;
import com.hrp.analyzer.util.StringUtils;
import com.hrp.analyzer.util.compat.PrintLog;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;


/**
 * @author hrp
 * @date 2021/2/12 18:36
 */

public class SearchSpider extends AbstractPageable<Novel> {
    /**
     * 规则列表
     */
    private final List<AnalyzerRule> rules;
    /**
     * 一页抓取完成后的回调
     */

    private Consumer<List<Novel>> pageConsumer;

    public void setPageConsumer(Consumer<List<Novel>> pageConsumer) {
        this.pageConsumer = pageConsumer;
    }

    /**
     * 关键词
     */

    private String keyword;

    public String getKeyword() {
        return keyword;
    }

    public SearchSpider(List<AnalyzerRule> rules) {
        this.rules = rules;
    }

    /**
     * 搜索
     *
     * @param keyword 关键词
     */
    public void search(String keyword) throws IOException {
        this.keyword = keyword;
        super.firstLoad();
    }

    /**
     * 获取数据项的唯一ID
     *
     * @param item 数据项
     * @return 唯一标识
     */
    @Override
    protected String getUniqueId(Novel item) {
        return item.getUrl();
    }

    /**
     * 加载一页数据
     *
     * @param page 下一页页码
     * @return 是否已经搜索完成
     */
    @Override
    protected boolean loadPage(int page) {
        DebugHelper.debug("【搜索】：正在搜索第{}页", page);
        boolean hasMore = false;
        for (AnalyzerRule rule : rules) {
            if (!isVisited(rule.getSite()) && rule.getEnabled()) {
                try {
                    AtomicBoolean siteHasMore = new AtomicBoolean();
                    List<Novel> novels = NovelMatcher.search(page, keyword, rule, novel -> {
                        // 如果已经取消了则不再执行 并且如果有新的则认为还有下一页
                        if (!isCanceled()) {
                            // 调试模式不校验标题有效
                            if (DebugHelper.enabled() && StringUtils.isBlank(novel.getTitle())) {
                                return;
                            }
                            if (addItem(novel)) {
                                siteHasMore.set(true);
                            }
                        }
                    });
                    // 如果已经取消了则不再执行
                    if (isCanceled()) {
                        break;
                    }
                    // 如果还有新的 则认为还没有搜索完
                    if (siteHasMore.get()) {
                        PrintLog.log.verbose("站点:{} 搜索第{}页完成 关键词：《{}》，结果数量：{}", rule.getSite(), page, keyword, novels.size());
                        if (pageConsumer != null) {
                            pageConsumer.accept(novels);
                        }
                        hasMore = true;
                    } else {
                        // 没有新的小说 则认为这个书源已经被搜索完了
                        addVisited(rule.getSite());
                        PrintLog.log.verbose("站点:{} 搜索结束 关键词：《{}》，共{}页", rule.getSite(), keyword, page - 1);
                    }
                } catch (IOException e) {
                    // 请求异常 则认为这个书源已经被搜索完了
                    addVisited(rule.getSite());
                    PrintLog.log.warn("搜索失败,page={},keyword={}，搜索规则：{}", page, keyword, rule.getSearch(), e);
                }
            }
        }
        return hasMore;
    }
}
